package com.ruoyi.app.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.app.util.CompressUtils;
import com.ruoyi.bizsys.domain.AppDeviceContactapplistRelative;
import com.ruoyi.bizsys.domain.ApplyAppData;
import com.ruoyi.bizsys.domain.DeviceAppList;
import com.ruoyi.bizsys.mapper.CustContactsRelativeMapper;
import com.ruoyi.bizsys.service.*;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.business.Vo.RulePremiseVo;
import com.ruoyi.business.common.riskRule.LoanRule;
import com.ruoyi.business.common.riskRule.RulePremiseService;
import com.ruoyi.business.service.DoCalCustReduce;
import com.ruoyi.business.service.IRaiseLimitService;
import com.ruoyi.common.VersionUtils;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author cyh
 * @date 2022/5/20 7:00 下午
 */
@Service
@Slf4j
public class AppListService {


    @Autowired
    LoanRule loanRule;

    @Autowired
    IAppDeviceContactapplistRelativeService iAppDeviceContactapplistRelativeService;

    @Autowired
    IRaiseLimitService raiseLimitService;

    @Autowired
    CustContactsRelativeMapper custContactsRelativeMapper;

    @Autowired
    IDeviceContactsService iDeviceContactsService;

    @Autowired
    IDeviceUserService iDeviceUserService;

    @Autowired
    IDeviceAppListService iDeviceAppListService;

    @Autowired
    IAppDeviceInfoService iAppDeviceInfoService;


    @Autowired
    private RulePremiseService premiseService;

    @Autowired
    DoCalCustReduce doCalCustReduce;


    @Autowired
    IAppDeviceInfoService appDeviceInfoService;


    @Autowired
    IApplyAppDataService iApplyAppDataService;

    /**
     * 保存用户授权app信息
     *
     * @param dataJson
     * @return
     */
    @Async("threadPoolTaskExecutor")
    public JSONObject appListLock(JSONObject dataJson, String userId, String custNo) {

        String actionType = dataJson.getString("actionType");
        String applyNo = dataJson.getString("applyNo");
        String batchNo = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        JSONArray appList = dataJson.getJSONArray("appList");
        //String applyNo = getApplyNo(custNo, actionType);

        DeviceAppList deviceAppList = new DeviceAppList();
        deviceAppList.setDeviceId(appDeviceInfoService.getDeviceIdByUserId(userId, DateUtils.getNowDate()));
        deviceAppList.setApplyNo(applyNo);
        deviceAppList.setActionType(actionType);

        if (StringUtils.isNotBlank(applyNo)) {
            long start = System.currentTimeMillis();
            saveAppListDB(appList, deviceAppList, custNo, userId);
            long end = System.currentTimeMillis();
            log.info("appList占用时间，耗时：" + (end - start) + " ms");
        }

        return new JSONObject();
    }

    /**
     * 保存用户授权app信息
     *
     * @param dataJson
     * @return
     */
    @Async("threadPoolTaskExecutor")
    public void appListV228(JSONObject dataJson, String userId, String custNo, String appVersion) {

        //2.3.1开始解压缩
        String appStr = dataJson.getString("appList");
        if (VersionUtils.compareVersion(appVersion, "2.3.1") >= 0) {
            appStr = CompressUtils.unCompress(appStr);
        }
        JSONArray appList = JSONArray.parseArray(appStr);

        String fingerprint = dataJson.getString("fingerprint");
        //String applyNo = getApplyNo(custNo, actionType);

        String applyNo = IdUtils.reqId();

        DeviceAppList deviceAppList = new DeviceAppList();
        deviceAppList.setDeviceId(fingerprint);
        deviceAppList.setApplyNo(applyNo);

        if (StringUtils.isNotBlank(applyNo)) {
            long start = System.currentTimeMillis();

            saveAppListDBV228(userId, appList, deviceAppList);
            premiseService.deviceRulePremise(custNo, applyNo, "appsFlag");
//            RulePremiseVo rulePremiseVo = RulePremiseVo.builder().custNo(custNo).userId(userId).fingerprint(fingerprint).build();
//            premiseService.rulePremiseV228(rulePremiseVo);

            long end = System.currentTimeMillis();
            log.info("app   List占用时间，耗时：" + (end - start) + " ms");
        }
    }


    public void saveAppListDBV228(String userId, JSONArray appList, DeviceAppList deviceAppList) {

        //查找七天内是否有上传通讯录数据
        String appNo = iAppDeviceContactapplistRelativeService.getBy7DdayData(deviceAppList.getDeviceId(), userId, 2);
        if (StringUtils.isBlank(appNo)) {

            List<ApplyAppData> appData = getAppData(appList);
            log.info("客户APP授权记录为0，No:{}", appData.size());
            if (Func.isEmpty(appData)) {
                throw new BusinessException(RspEnmu.PARAM_CANNOT_NULL);
            }

            deviceAppList.setAppIds(iApplyAppDataService.getAppIds(appData));
            iDeviceAppListService.insertDeviceAppList(deviceAppList);

            AppDeviceContactapplistRelative appDeviceContactapplistRelative = new AppDeviceContactapplistRelative();
            appDeviceContactapplistRelative.setRelativeNo(deviceAppList.getApplyNo());
            appDeviceContactapplistRelative.setFingerprint(deviceAppList.getDeviceId());
            appDeviceContactapplistRelative.setType(2);
            appDeviceContactapplistRelative.setUserId(userId);
            iAppDeviceContactapplistRelativeService.insertAppDeviceContactapplistRelative(appDeviceContactapplistRelative);
        }

    }


    public void saveAppListDB(JSONArray appList, DeviceAppList deviceAppList, String custNo, String userId) {

        //APP是否为空
        List<ApplyAppData> appData = getAppData(appList);
        if (Func.isEmpty(appData)) {
            log.info("客户APP授权记录为0，actionType:{},No:{}", deviceAppList.getActionType(), userId);
            throw new BusinessException(RspEnmu.PARAM_CANNOT_NULL);
        }
        String actionType = deviceAppList.getActionType();

        //设备指纹是否一致
        String sourceFingerprint = iAppDeviceInfoService.getDeviceIdByUserId(userId, DateUtils.getNowDate());
        boolean consistent = loanRule.fingerprintsSame(sourceFingerprint, deviceAppList.getApplyNo(), custNo);
        log.info("设备指纹是否一致，sourceFingerprint:{}", sourceFingerprint);

        //授信
        if (BizConstants.RULE_TYPE_APPLY.equals(actionType)) {
            QueryWrapper<DeviceAppList> applyAppListQueryWrapper = new QueryWrapper<>();
            applyAppListQueryWrapper.eq("apply_no", deviceAppList.getApplyNo());
            //设备指纹不一致  查找流水号是否在数据库里面已经存储
            if (!consistent || iDeviceAppListService.count(applyAppListQueryWrapper) == 0) {
                deviceAppList.setAppIds(iApplyAppDataService.getAppIds(appData));
                iDeviceAppListService.insertDeviceAppList(deviceAppList);
            }
        }
        // 提现
        if (BizConstants.RULE_TYPE_LOAN.equals(actionType)) {
            //设备指纹不一致 查找7天内是否上传过app
            if (!consistent || StringUtils.isBlank(iDeviceAppListService.get7DaysAppList(sourceFingerprint))) {
                deviceAppList.setAppIds(iApplyAppDataService.getAppIds(appData));
                iDeviceAppListService.insertDeviceAppList(deviceAppList);
            }
        }
        if (Func.isEmpty(sourceFingerprint)) {
            sourceFingerprint = "";
        }
        RulePremiseVo rulePremiseVo = RulePremiseVo.builder().custNo(custNo).type(actionType).serialNo(deviceAppList.getApplyNo()).fingerprint(sourceFingerprint.toString()).build();
        premiseService.rulePremise(rulePremiseVo, "appsFlag");
    }


    public List<ApplyAppData> getAppData(JSONArray dataJsonArr) {
        List<ApplyAppData> appDataList = new ArrayList<>();
        for (int i = 0; i < dataJsonArr.size(); i++) {
            JSONObject tempObject = dataJsonArr.getJSONObject(i);
            if (Func.isEmpty(tempObject.get("appName")) || tempObject.getString("appName").length() > 200) {
                continue;
            }
            appDataList.add(JSON.toJavaObject(tempObject, ApplyAppData.class));
        }
        return appDataList;
    }


}
